using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using UserManagement.Models;
using UserManagement.Services;

namespace UserManagement.ViewModels
{
    public class AddUserViewModel : BindableBase, INavigationAware, INotifyDataErrorInfo
    {
        private readonly IUserService _userService;
        private readonly IRegionManager _regionManager;
        
        private User _user = new();
        private string _title = "添加用户";
        private string _saveButtonText = "保存";
        private string _statusMessage = "";
        private bool _isEditMode = false;
        private int _editingUserId = 0;

        // ErrorsContainer相关
        private readonly Dictionary<string, List<string>> _errors = new();
        private readonly ObservableCollection<string> _errorMessages = new();

        public AddUserViewModel(IUserService userService, IRegionManager regionManager)
        {
            _userService = userService;
            _regionManager = regionManager;

            // 初始化Commands
            SaveCommand = new DelegateCommand(async () => await SaveUserAsync(), CanSave);
            CancelCommand = new DelegateCommand(Cancel);
            ClearCommand = new DelegateCommand(Clear);

            // 监听User属性变化以触发验证
            User.PropertyChanged += (s, e) => 
            {
                ValidateProperty(e.PropertyName!);
                SaveCommand.RaiseCanExecuteChanged();
            };
        }

        #region Properties

        public User User
        {
            get { return _user; }
            set 
            { 
                if (_user != null)
                    _user.PropertyChanged -= (s, e) => ValidateProperty(e.PropertyName!);
                
                SetProperty(ref _user, value); 
                
                if (_user != null)
                    _user.PropertyChanged += (s, e) => ValidateProperty(e.PropertyName!);
            }
        }

        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public string SaveButtonText
        {
            get { return _saveButtonText; }
            set { SetProperty(ref _saveButtonText, value); }
        }

        public string StatusMessage
        {
            get { return _statusMessage; }
            set { SetProperty(ref _statusMessage, value); }
        }

        public ObservableCollection<string> ErrorMessages => _errorMessages;

        public Dictionary<string, string> Errors
        {
            get
            {
                return _errors.ToDictionary(
                    kvp => kvp.Key,
                    kvp => string.Join("; ", kvp.Value)
                );
            }
        }

        #endregion

        #region Commands

        public DelegateCommand SaveCommand { get; }
        public DelegateCommand CancelCommand { get; }
        public DelegateCommand ClearCommand { get; }

        #endregion

        #region Command Methods

        private bool CanSave()
        {
            return !HasErrors && !string.IsNullOrWhiteSpace(User.Name) && !string.IsNullOrWhiteSpace(User.Email);
        }

        private async Task SaveUserAsync()
        {
            try
            {
                ValidateAllProperties();
                
                if (HasErrors)
                {
                    StatusMessage = "请修正验证错误";
                    return;
                }

                StatusMessage = _isEditMode ? "正在更新用户..." : "正在保存用户...";

                bool success;
                if (_isEditMode)
                {
                    User.Id = _editingUserId;
                    success = await _userService.UpdateUserAsync(User);
                }
                else
                {
                    success = await _userService.AddUserAsync(User);
                }

                if (success)
                {
                    StatusMessage = _isEditMode ? "用户更新成功" : "用户保存成功";
                    
                    // 延迟一下再导航，让用户看到成功消息
                    await Task.Delay(1000);
                    _regionManager.RequestNavigate("ContentRegion", "UserListView");
                }
                else
                {
                    StatusMessage = _isEditMode ? "用户更新失败" : "用户保存失败";
                }
            }
            catch (Exception ex)
            {
                StatusMessage = $"操作失败: {ex.Message}";
            }
        }

        private void Cancel()
        {
            _regionManager.RequestNavigate("ContentRegion", "UserListView");
        }

        private void Clear()
        {
            if (_isEditMode) return; // 编辑模式下不允许清空

            User = new User();
            ClearErrors();
            StatusMessage = "表单已清空";
        }

        #endregion

        #region Validation (ErrorsContainer Implementation)

        public bool HasErrors => _errors.Any(kvp => kvp.Value.Any());

        public event EventHandler<DataErrorsChangedEventArgs>? ErrorsChanged;

        public System.Collections.IEnumerable GetErrors(string? propertyName)
        {
            if (string.IsNullOrEmpty(propertyName) || !_errors.ContainsKey(propertyName))
                return Enumerable.Empty<string>();
            
            return _errors[propertyName];
        }

        private void ValidateProperty(string propertyName)
        {
            ClearErrors(propertyName);

            var validationContext = new ValidationContext(User) { MemberName = propertyName };
            var validationResults = new List<ValidationResult>();

            Validator.TryValidateProperty(
                typeof(User).GetProperty(propertyName)?.GetValue(User),
                validationContext,
                validationResults);

            if (validationResults.Any())
            {
                AddErrors(propertyName, validationResults.Select(r => r.ErrorMessage ?? "").Where(m => !string.IsNullOrEmpty(m)));
            }

            // 自定义验证规则
            switch (propertyName)
            {
                case nameof(User.Email):
                    if (!string.IsNullOrEmpty(User.Email) && !IsValidEmail(User.Email))
                    {
                        AddError(propertyName, "邮箱格式不正确");
                    }
                    break;
                case nameof(User.Age):
                    if (User.Age < 18 || User.Age > 100)
                    {
                        AddError(propertyName, "年龄必须在18-100之间");
                    }
                    break;
            }

            UpdateErrorMessages();
            SaveCommand.RaiseCanExecuteChanged();
        }

        private void ValidateAllProperties()
        {
            var properties = typeof(User).GetProperties()
                .Where(p => p.CanRead && p.CanWrite)
                .Select(p => p.Name);

            foreach (var property in properties)
            {
                ValidateProperty(property);
            }
        }

        private void AddError(string propertyName, string error)
        {
            if (!_errors.ContainsKey(propertyName))
                _errors[propertyName] = new List<string>();

            if (!_errors[propertyName].Contains(error))
            {
                _errors[propertyName].Add(error);
                ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
                RaisePropertyChanged(nameof(Errors));
                RaisePropertyChanged(nameof(HasErrors));
            }
        }

        private void AddErrors(string propertyName, IEnumerable<string> errors)
        {
            foreach (var error in errors)
            {
                AddError(propertyName, error);
            }
        }

        private void ClearErrors(string? propertyName = null)
        {
            if (propertyName == null)
            {
                var propertiesToClear = _errors.Keys.ToList();
                _errors.Clear();
                foreach (var property in propertiesToClear)
                {
                    ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(property));
                }
            }
            else if (_errors.ContainsKey(propertyName))
            {
                _errors.Remove(propertyName);
                ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
            }

            RaisePropertyChanged(nameof(Errors));
            RaisePropertyChanged(nameof(HasErrors));
            UpdateErrorMessages();
        }

        private void UpdateErrorMessages()
        {
            _errorMessages.Clear();
            foreach (var errors in _errors.Values)
            {
                foreach (var error in errors)
                {
                    _errorMessages.Add(error);
                }
            }
        }

        private bool IsValidEmail(string email)
        {
            try
            {
                var addr = new System.Net.Mail.MailAddress(email);
                return addr.Address == email;
            }
            catch
            {
                return false;
            }
        }

        #endregion

        #region INavigationAware

        public async void OnNavigatedTo(NavigationContext navigationContext)
        {
            // 检查是否是编辑模式
            if (navigationContext.Parameters.ContainsKey("UserId"))
            {
                _isEditMode = true;
                _editingUserId = navigationContext.Parameters.GetValue<int>("UserId");
                Title = "编辑用户";
                SaveButtonText = "更新";

                try
                {
                    var user = await _userService.GetUserByIdAsync(_editingUserId);
                    if (user != null)
                    {
                        // 创建用户的副本以避免直接修改原对象
                        User = new User
                        {
                            Id = user.Id,
                            Name = user.Name,
                            Email = user.Email,
                            Age = user.Age,
                            IsActive = user.IsActive,
                            CreateDate = user.CreateDate
                        };
                    }
                }
                catch (Exception ex)
                {
                    StatusMessage = $"加载用户数据失败: {ex.Message}";
                }
            }
            else
            {
                _isEditMode = false;
                _editingUserId = 0;
                Title = "添加用户";
                SaveButtonText = "保存";
                User = new User();
                ClearErrors();
            }
        }

        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {
            // 清理工作
        }

        #endregion
    }
}